package com.ruoyi.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.ruoyi.center.domain.NoticeCenter;
import com.ruoyi.center.service.INoticeCenterService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.common.util.ListConvertMap;
import com.common.util.MergeDataSource;
import com.param.impl.IdParam;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.withdrawal.domain.Withdrawal;
import com.ruoyi.withdrawal.service.IWithdrawalService;

import io.swagger.annotations.ApiOperation;

import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.management.domain.CommissionManagement;
import com.ruoyi.management.domain.CommissionManagementDetail;
import com.ruoyi.management.service.ICommissionManagementDetailService;
import com.ruoyi.management.service.ICommissionManagementService;
import com.ruoyi.user.domain.MgUser;
import com.ruoyi.user.service.IMgUserService;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 提现管理Controller
 * 
 * @author ruoyi
 * @date 2024-01-17
 */
@RestController
@RequestMapping("/withdrawal/withdrawal")
public class WithdrawalController extends BaseController {
	@Autowired
	private IWithdrawalService withdrawalService;

	private IMgUserService userService;
	
	private ICommissionManagementService commissionManagementService;

	private ICommissionManagementDetailService commissionManagementDetailService;

	@Autowired
	private INoticeCenterService noticeCenterService;
	
	@Resource
	public void setCommissionManagementService(ICommissionManagementService commissionManagementService) {
		this.commissionManagementService = commissionManagementService;
	}

	/**
	 * 查询提现管理列表
	 */
	@ApiOperation(value = "提现列表")
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:list')")
	@GetMapping("/list")
	public TableDataInfo list(Withdrawal withdrawal) {

		
		MemInfo info = condtionParse(withdrawal);
		
		if (!info.status) {
			return getDataTable(new ArrayList<>(0));
		}
		
		withdrawal.setUserIds(info.userIds);
		
		
		startPage();
		List<Withdrawal> list = withdrawalService.selectList(withdrawal);

		if (0 == list.size()) {
			return getDataTable(new ArrayList<>(0));
		}

		userAfter(list, info.getUsers());

		return getDataTable(list);
	}

	protected MemInfo condtionParse(Withdrawal withdrawal) {
		
		MemInfo memInfo = new MemInfo();
		
		List<MgUser> listBySearch = null;
		
		int[] userIds = null;
		if (null != withdrawal.getPhone() || null != withdrawal.getEmail()) {

			listBySearch = userService.listBySearch(withdrawal);

			int size = listBySearch.size();
			if (0 != size) {

				Integer userId = withdrawal.getUserId();
				
				int flag = 6;
				
				userIds = new int[size];
				
				for (MgUser user : listBySearch) {
					
					if (userId!= null && userId!= user.getId()) {
                        flag = 5;
                    }
					
                    userIds[--size] = user.getId();
				}
				
				if (5 == flag) {
					memInfo.setStatus(false);
				}
			} else {
				// 说明找不到
				memInfo.setStatus(false);
                return memInfo;
			}
			
			memInfo.setUserIds(userIds);
			memInfo.setStatus(true);
			memInfo.setUsers(listBySearch);
			// 说明找不到
			return memInfo;
		}
		
		return memInfo;
	}

	private void userAfter(List<Withdrawal> list, List<MgUser> userList) {
		if (0 == userList.size()) {
			userList  = userService
	                .getUserList(list.stream().mapToLong(e -> e.getUserId()).distinct().toArray());
		}
		
		Map<Integer, MgUser> listToMap = ListConvertMap.listToMap(userList, MgUser::getId);

		MergeDataSource<Withdrawal> mergeDataSource = new MergeDataSource<Withdrawal>(list);

		mergeDataSource.mergeRelease(Withdrawal::getUserId, listToMap, (Withdrawal w, MgUser u) -> {
			w.setPhone(u.getMobile());

			w.setEmail(u.getEmail());

			return w;
		});
	}

	
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:record')")
	@GetMapping("/listByMe")
	public TableDataInfo listByMe(@Validated IdParam param) {
		
		startPage();
		
		List<Withdrawal> list = withdrawalService.selectListById(param.getId());
		
		return getDataTable(list);
	}
	
	
	/**
	 * 导出提现管理列表
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:export')")
	@Log(title = "提现管理", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	public void export(HttpServletResponse response, Withdrawal withdrawal) {
		
		MemInfo info = condtionParse(withdrawal);
		
		if (!info.status) {
			return ;
		}
		
		withdrawal.setUserIds(info.userIds);
		
		
		List<Withdrawal> list = withdrawalService.selectList(withdrawal);
		userAfter(list, info.getUsers());
		ExcelUtil<Withdrawal> util = new ExcelUtil<Withdrawal>(Withdrawal.class);
		util.exportExcel(response, list, "提现管理数据");
	}

	/**
	 * 获取提现管理详细信息
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:query')")
	@GetMapping(value = "/{id}")
	public AjaxResult getInfo(@PathVariable("id") Integer id) {
		return success(withdrawalService.selectById(id));
	}

	/**
	 * 新增提现管理
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:add')")
	@Log(title = "提现管理", businessType = BusinessType.INSERT)
	@PostMapping
	public AjaxResult add(@RequestBody Withdrawal withdrawal) {
		return toAjax(withdrawalService.insert(withdrawal));
	}

	/**
	 * 修改提现管理
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:edit')")
	@Log(title = "提现管理", businessType = BusinessType.UPDATE)
	@PutMapping
	public AjaxResult edit(@RequestBody Withdrawal withdrawal) {
		return toAjax(withdrawalService.update(withdrawal));
	}

	/**
	 * 申请提现
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:apply')")
	@Log(title = "提现管理", businessType = BusinessType.UPDATE)
	@PutMapping("apply")
	@Transactional
	public AjaxResult apply(@RequestBody Withdrawal withdrawal) {

		Integer id = withdrawal.getId();
		
		if (null == id) {
			return AjaxResult.error("id不能为空");
		}
		
		Integer status = withdrawal.getStatus();

		if (null == status) {
			return AjaxResult.error("状态不能为空");
		}

		String reason = withdrawal.getReason();

		if (status == 1 && null == reason) {
			return AjaxResult.error("审核原因不能为空");
		}
		
		Withdrawal withdrawalForUpdate = this.withdrawalService.getWithdrawalForUpdate(id);
		
		if (null == withdrawalForUpdate) {
			return AjaxResult.error("提现申请不存在");
		}
		
		if (2 == withdrawalForUpdate.getStatus()) {
			return AjaxResult.error("提现申请已通过");
		}

		int update = withdrawalService.update(withdrawal);
		
		BigDecimal amount = withdrawalForUpdate.getAmount();
		
		if (1 == status) {
			// 还原数据 拒绝
			CommissionManagement commissionManagement = new CommissionManagement();
			
			commissionManagement.setUserId(withdrawalForUpdate.getUserId());
			
			commissionManagement.setWithdrawableAmount(amount);
			
			commissionManagement.setFreezeAmount(amount);
			
			commissionManagementService.updateMoney(commissionManagement);

			NoticeCenter center = new NoticeCenter();

			center.setUserId( withdrawalForUpdate.getUserId());


			center.setNoticeContent("您发起的【￥" + amount + "】提现申请未通过，审核原因："+reason);

			center.setPlatform(0);

			center.setNoticeType(5);

			center.setTitle("提现申请");

			center.setTypeId(id);

			noticeCenterService.insert(center);
			
		} else if (2 == status) {
			// 审核成功 添加佣金记录
			Integer userId = withdrawalForUpdate.getUserId();
			CommissionManagement commissonManagent = commissionManagementService.getCommissonManagent(userId);
			
			// 减少冻结金额
			CommissionManagement updateCommissionManagement = new CommissionManagement();
			
			updateCommissionManagement.setId(commissonManagent.getId());
			
			updateCommissionManagement.setFreezeAmount(commissonManagent.getFreezeAmount().subtract(amount));
			
			commissionManagementService.update(updateCommissionManagement);
			
			Integer commissonManagentId = commissonManagent.getId();
			
			CommissionManagementDetail commissionManagementDetail = commissionManagementDetailService.generate(commissonManagentId, amount, userId);
			
			commissionManagementDetailService.insert(commissionManagementDetail);
			NoticeCenter center = new NoticeCenter();

			center.setUserId( withdrawalForUpdate.getUserId());


			center.setNoticeContent("您发起的【￥" + amount + "】提现申请已通过，预计1-3个工作日内到账，请注意查收");

			center.setPlatform(0);

			center.setNoticeType(5);

			center.setTitle("提现申请");

			center.setTypeId(id);

			noticeCenterService.insert(center);
		}
		
		return toAjax(update);

	}

	/**
	 * 申请提现
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:updateAmountStatus')")
	@Log(title = "提现管理", businessType = BusinessType.UPDATE)
	@PutMapping("updateAmountStatus")
	public AjaxResult updateAmountStatus(@RequestBody Withdrawal withdrawal) {

		Integer id = withdrawal.getId();

		if (null == id) {
			return AjaxResult.error("状态不能为空");
		}

		Integer status = withdrawal.getAmountStatus();

		if (null == status) {
			return AjaxResult.error("状态不能为空");
		}

		Withdrawal insert = new Withdrawal();

		insert.setId(id);

		insert.setAmountStatus(status);

		return toAjax(withdrawalService.update(insert));

	}

	/**
	 * 删除提现管理
	 */
	@PreAuthorize("@ss.hasPermi('withdrawal:withdrawal:remove')")
	@Log(title = "提现管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
	public AjaxResult remove(@PathVariable Integer[] ids) {
		return toAjax(withdrawalService.deleteByIds(ids));
	}

	@Resource
	public void setUserService(IMgUserService userService) {
		this.userService = userService;
	}
	
	@Resource
	public void setCommissionManagementDetailService(ICommissionManagementDetailService commissionManagementDetailService) {
		this.commissionManagementDetailService = commissionManagementDetailService;
	}
}
